GLU
Gated Linear Unit(门控线性单元)算子。该算子将输入张量在指定维度(split_dim)上分割成两个相等的部分(A和B),然后对第二部分(B)应用Sigmoid激活函数,并将其与第一部分(A)逐元素相乘。
\[\text{out} = A \otimes \sigma(B)\]
其中,A和B是输入张量沿 split_dim 维度分割后的两个子张量,\(\sigma\) 是Sigmoid函数,\(\otimes\) 表示逐元素乘法。
- 输入:
in_data - 输入张量的数据地址。
split_data - 一个指针数组,用于存放分割后的子张量地址(作为临时缓冲区)。
out_data - 输出张量的数据地址。
ndim - 输入张量的维度数量。
split_dim - 执行分割操作的目标维度轴。
input_shape - 指向一个整数数组的指针,该数组描述了输入张量的形状。
num_split - 分割的数量,对于GLU操作,此值应为2。
split_sizes - 指向一个整数数组的指针,该数组描述了每个子张量在
split_dim维度上的大小。strides - 指向一个整数数组的指针,用于存放为张量索引预先计算好的步长。
len - 输出张量中的元素总数。
core_mask - 核掩码 (仅共享存储版本需要)。
- 输出:
out_data - 存储GLU计算结果的张量。其形状与输入张量相同,但在
split_dim维度上的大小减半。
- 支持平台:
FT78NEMT7004
备注
FT78NE支持fp32和int8类型。
MT7004支持fp16和fp32类型。
共享存储版本:
-
void i8_glu_s(int8_t *in_data, int8_t **split_data, int8_t *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len, int core_mask)
-
void hp_glu_s(half *in_data, half **split_data, half *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len, int core_mask)
-
void fp_glu_s(float *in_data, float **split_data, float *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len, int core_mask)
C调用示例:
1// 7004平台, fp32示例
2#include <stdio.h>
3#include "glu.h"
4
5int main(int argc, char* argv[]) {
6 float *in_data = (float *)0xA0000000; // input在DDR空间
7 float *out_data = (float *)0xC0000000; // output在DDR空间
8 float *split_data_buf[2]; // 临时缓冲区指针
9 // ... (需要为split_data_buf分配内存)
10
11 // 假设张量属性已定义
12 int ndim = 2;
13 int split_dim = 1;
14 int input_shape[] = {2, 4};
15 int num_split = 2;
16 int split_sizes[] = {2, 2};
17 int len = 4;
18 int strides[2]; // 需要预先计算
19 int core_mask = 0xff;
20
21 fp_glu_s(in_data, split_data_buf, out_data, ndim, split_dim, input_shape, num_split, split_sizes, strides, len, core_mask);
22 return 0;
23}
私有存储版本:
-
void i8_glu_p(int8_t *in_data, int8_t **split_data, int8_t *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len)
-
void hp_glu_p(half *in_data, half **split_data, half *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len)
-
void fp_glu_p(float *in_data, float **split_data, float *out_data, int ndim, int split_dim, int *input_shape, int num_split, int *split_sizes, int *strides, int len)
C调用示例:
1// 7004平台, fp32示例
2#include <stdio.h>
3#include "glu.h"
4
5int main(int argc, char* argv[]) {
6 float *in_data = (float *)0x10000000; // input在L2空间
7 float *out_data = (float *)0x10001000; // output在L2空间
8 float *split_data_buf[2]; // 临时缓冲区指针
9 // ... (需要为split_data_buf分配内存)
10
11 // 假设张量属性已定义
12 int ndim = 2;
13 int split_dim = 1;
14 int input_shape[] = {2, 4};
15 int num_split = 2;
16 int split_sizes[] = {2, 2};
17 int len = 4;
18 int strides[2]; // 需要预先计算
19
20 fp_glu_p(in_data, split_data_buf, out_data, ndim, split_dim, input_shape, num_split, split_sizes, strides, len);
21 return 0;
22}